package dwei.ui.core
{
	import flash.display.Stage;
	import flash.events.Event;

	public class ValidateMgr
	{
//============================================================================
//PROPERTY
//============================================================================
		private static var _stage:Stage;
		
		private static var _listeningForRender:Boolean = false;
		
		private static const _propertiesQueue:Array = [];
		private static var _propertiesDirty:Boolean = false;
		
		private static const _sizeQueue:Array = [];
		private static var _sizeDirty:Boolean = false;
		
		private static const _displayListQueue:Array = [];
		private static var _displayListDirty:Boolean = false;
//============================================================================
//METHOD
//============================================================================
		//====================================================================
		//PUBLIC
		//====================================================================
		public static function initialize(uiStage:Stage):void
		{
			_stage = uiStage;
			
		}
		public static function invalidateProperties(target:IValidate):void
		{
			if (_propertiesQueue.indexOf(target) != -1) return;
			_propertiesQueue.push(target);
			if ((!_propertiesDirty) && (_stage != null))
			{
				_propertiesDirty = true;
				if (!_listeningForRender)
				{
					_stage.addEventListener(Event.RENDER, stageRender_handler);
					_listeningForRender = true;
					_stage.invalidate();
				}
			}
		}
		public static function invalidateSize(target:IValidate):void
		{
			if (_sizeQueue.indexOf(target) != -1) return;
			_sizeQueue.push(target);
			if ((!_sizeDirty) && (_stage != null))
			{
				_sizeDirty = true;
				if (!_listeningForRender)
				{
					_stage.addEventListener(Event.RENDER, stageRender_handler);
					_listeningForRender = true;
					_stage.invalidate();
				}
			}
		}
		public static function invalidateDisplayList(target:IValidate):void
		{
			if (_displayListQueue.indexOf(target) != -1) return;
			_displayListQueue.push(target);
			if ((!_displayListDirty) && (_stage != null))
			{
				_displayListDirty = true;
				if (!_listeningForRender)
				{
					_stage.addEventListener(Event.RENDER, stageRender_handler);
					_listeningForRender = true;
					_stage.invalidate();
				}
			}
		}
//============================================================================
//HANDLER
//============================================================================
		private static function stageRender_handler(event:Event):void
		{
			var index:int;
			var target:IValidate;
			if (_propertiesDirty)
			{
				while (_propertiesQueue.length > 0)
				{
					_propertiesQueue.sortOn("nestLevel", Array.NUMERIC | Array.DESCENDING);
					target = _propertiesQueue.pop();
					target.validateProperties();
				}
				_propertiesDirty = false;
			}
			if (_sizeDirty)
			{
				while (_sizeQueue.length > 0)
				{
					_sizeQueue.sortOn("nestLevel", Array.NUMERIC);
					target = _sizeQueue.pop();
					target.validateSize();
				}
				_sizeDirty = false;
			}
			if (_displayListDirty)
			{
				while (_displayListQueue.length > 0)
				{
					_displayListQueue.sortOn("nestLevel", Array.NUMERIC | Array.DESCENDING);
					target = _displayListQueue.pop();
					target.validateDisplayList();
					if (!target.initialized) target.initialized = true;
				}
				_displayListDirty = false;
			}
			if (_propertiesDirty || _sizeDirty || _displayListDirty) return;
			_stage.removeEventListener(Event.RENDER, stageRender_handler);
			_listeningForRender = false;
		}
//============================================================================
//GETTER/SETTER
//============================================================================
		public function get stage():Stage
		{
			return _stage;
		}
	}
}